// $codepro.audit.disable numericLiterals
/**
 * uses view package
 */
package javamonsters.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import javamonsters.model.InventoryItem;
import javamonsters.model.Marketplace;
import javamonsters.model.SolarSystem;
import javamonsters.model.TradeGood;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.UIManager;


/**
 * @author Evan
 * @version 1.0
 */
public class UniverseSideView extends JPanel implements View, Serializable {
	
	/**
	 * serialize
	 */
	private static final long serialVersionUID = 4293831033925755308L;

	/**
	 * JLabel for universe
	 */
	private final JLabel systemLabel, techLevelLabel, currentFuelLabel, fuelCostLabel;
	
	/**
	 * JButtons for universe
	 */
	private final JButton travelButton, saveButton;
	
	/**
	 * instance variable for SolarSystem
	 */
	private SolarSystem currSystem;

	/**
	 * instance variable for JScrollPane
	 */
	private final JScrollPane scrollPane;
	
	/**
	 * instance variable for JList
	 */
	private final JList cargoList;
	
	/**
	 * instance variable for JLabel
	 */
	private final JLabel cargoTitleLabel;
	
	/**
	 * instance variable for DefaultListModel
	 */
	private DefaultListModel cargoModel;
	
	/**
	 * fonts
	 */
	private final Font tabFont, systemFont, infoFont, listTitleFont;
	
	/**
	 * instance variable for JLabel
	 */
	private final JLabel attributeTagLabel;
	
	/**
	 * instance variable for JLabel
	 */
	private final JLabel attributeLabel;
	
	/**
	 * instance variables for controller spaceTradersParent
	 */
	private final SpaceTraders spaceTradersParent;

	/**
	 * constructor for UniverseSideView
	 * @param spaceTradersParent the main game controller
	 * @throws FontFormatException
	 * @throws IOException
	 */
	public UniverseSideView(SpaceTraders spaceTradersParent)
			throws FontFormatException, IOException {
		super.setBackground(UIManager.getColor("Panel.background"));
		
		this.spaceTradersParent = spaceTradersParent;
		
		final File fontFile = new File("Fonts/Compass.ttf");
		final Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
		tabFont = font.deriveFont(9f);
		systemFont = font.deriveFont(18f);
		infoFont = font.deriveFont(10f);
		listTitleFont = font.deriveFont(14f);
		
		super.setLayout(new GridLayout(1, 0, 0, 0));
		super.setPreferredSize(new Dimension(320, 380));
		final JTabbedPane mapPane = new JTabbedPane(JTabbedPane.TOP) { // $codepro.audit.disable staticMemberAccess
			public Color getForegroundAt(int index){  
		          if(getSelectedIndex() == index) return Color.BLACK;  
		          	return Color.WHITE;  
		      }  
		};  
		mapPane.setBackground(Color.BLACK);
		mapPane.setFont(tabFont);
		super.add(mapPane);
		
		final JPanel systemInfoPanel = new JPanel();
		systemInfoPanel.setBackground(Color.BLACK);
		//systemInfoPanel.setPreferredSize(new Dimension(320,300));
		mapPane.addTab("System Info", null, systemInfoPanel, null);
		final GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{281, 202};
		gridBagLayout.rowHeights = new int[]{14, 33, 49, 10, 10, 10, 10, 56, 0, 0, 0};
		gridBagLayout.columnWeights = new double[]{0.0, 0.0};
		gridBagLayout.rowWeights = new double[]{
				0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		systemInfoPanel.setLayout(gridBagLayout);
		
		systemLabel = new JLabel("System");
		systemLabel.setForeground(Color.WHITE);
		systemLabel.setFont(systemFont);
		final GridBagConstraints gbc_systemLabel = new GridBagConstraints();
		gbc_systemLabel.gridwidth = 2;
		gbc_systemLabel.insets = new Insets(0, 0, 5, 0);
		gbc_systemLabel.gridx = 0;
		gbc_systemLabel.gridy = 1;
		systemInfoPanel.add(systemLabel, gbc_systemLabel);
		
		final JLabel techLevelTagLabel = new JLabel("Tech Level:");
		techLevelTagLabel.setForeground(Color.WHITE);
		techLevelTagLabel.setFont(infoFont);
		final GridBagConstraints gbc_techLevelTagLabel = new GridBagConstraints();
		gbc_techLevelTagLabel.insets = new Insets(0, 0, 5, 5);
		gbc_techLevelTagLabel.gridx = 0;
		gbc_techLevelTagLabel.gridy = 3;
		systemInfoPanel.add(techLevelTagLabel, gbc_techLevelTagLabel);
		
		techLevelLabel = new JLabel("Level");
		techLevelLabel.setForeground(Color.WHITE);
		techLevelLabel.setFont(infoFont);
		final GridBagConstraints gbc_techLevelLabel = new GridBagConstraints();
		gbc_techLevelLabel.anchor = GridBagConstraints.WEST;
		gbc_techLevelLabel.insets = new Insets(0, 0, 5, 0);
		gbc_techLevelLabel.gridx = 1;
		gbc_techLevelLabel.gridy = 3;
		systemInfoPanel.add(techLevelLabel, gbc_techLevelLabel);
		
		attributeTagLabel = new JLabel("System Attribute: ");
		attributeTagLabel.setForeground(Color.WHITE);
		attributeTagLabel.setFont(infoFont);
		final GridBagConstraints gbc_attributeTagLabel = new GridBagConstraints();
		gbc_attributeTagLabel.insets = new Insets(0, 0, 5, 5);
		gbc_attributeTagLabel.gridx = 0;
		gbc_attributeTagLabel.gridy = 4;
		systemInfoPanel.add(attributeTagLabel, gbc_attributeTagLabel);
		
		attributeLabel = new JLabel("Attribute");
		attributeLabel.setForeground(Color.WHITE);
		attributeLabel.setFont(infoFont);
		final GridBagConstraints gbc_attributeLabel = new GridBagConstraints();
		gbc_attributeLabel.anchor = GridBagConstraints.WEST;
		gbc_attributeLabel.insets = new Insets(0, 0, 5, 0);
		gbc_attributeLabel.gridx = 1;
		gbc_attributeLabel.gridy = 4;
		systemInfoPanel.add(attributeLabel, gbc_attributeLabel);
		
		final JLabel currentFuelTagLabel = new JLabel("Current Fuel:");
		currentFuelTagLabel.setForeground(Color.WHITE);
		currentFuelTagLabel.setFont(infoFont);
		final GridBagConstraints gbc_currentFuelTagLabel = new GridBagConstraints();
		gbc_currentFuelTagLabel.insets = new Insets(0, 0, 5, 5);
		gbc_currentFuelTagLabel.gridx = 0;
		gbc_currentFuelTagLabel.gridy = 5;
		systemInfoPanel.add(currentFuelTagLabel, gbc_currentFuelTagLabel);
		
		currentFuelLabel = new JLabel("Fuel");
		currentFuelLabel.setForeground(Color.WHITE);
		currentFuelLabel.setFont(infoFont);
		final GridBagConstraints gbc_currentFuelLabel = new GridBagConstraints();
		gbc_currentFuelLabel.anchor = GridBagConstraints.WEST;
		gbc_currentFuelLabel.insets = new Insets(0, 0, 5, 0);
		gbc_currentFuelLabel.gridx = 1;
		gbc_currentFuelLabel.gridy = 5;
		systemInfoPanel.add(currentFuelLabel, gbc_currentFuelLabel);
		
		final JLabel fuelCostTagLabel = new JLabel("Fuel Cost:");
		fuelCostTagLabel.setForeground(Color.WHITE);
		fuelCostTagLabel.setFont(infoFont);
		final GridBagConstraints gbc_fuelCostTagLabel = new GridBagConstraints();
		gbc_fuelCostTagLabel.insets = new Insets(0, 0, 5, 5);
		gbc_fuelCostTagLabel.gridx = 0;
		gbc_fuelCostTagLabel.gridy = 6;
		systemInfoPanel.add(fuelCostTagLabel, gbc_fuelCostTagLabel);
		
		fuelCostLabel = new JLabel("Cost");
		fuelCostLabel.setForeground(Color.WHITE);
		fuelCostLabel.setFont(infoFont);
		final GridBagConstraints gbc_fuelCost = new GridBagConstraints();
		gbc_fuelCost.anchor = GridBagConstraints.WEST;
		gbc_fuelCost.insets = new Insets(0, 0, 5, 0);
		gbc_fuelCost.gridx = 1;
		gbc_fuelCost.gridy = 6;
		systemInfoPanel.add(fuelCostLabel, gbc_fuelCost);
		
		travelButton = new JButton("Travel");
		travelButton.setFont(infoFont);
		final GridBagConstraints gbc_travelButton = new GridBagConstraints();
		gbc_travelButton.insets = new Insets(0, 0, 5, 0);
		gbc_travelButton.gridwidth = 2;
		gbc_travelButton.gridx = 0;
		gbc_travelButton.gridy = 8;
		systemInfoPanel.add(travelButton, gbc_travelButton);
		
		saveButton = new JButton("Save");
		saveButton.setFont(infoFont);
		final GridBagConstraints gbc_saveButton = new GridBagConstraints();
		gbc_saveButton.gridwidth = 2;
		gbc_saveButton.gridx = 0;
		gbc_saveButton.gridy = 9;
		systemInfoPanel.add(saveButton, gbc_saveButton);
		
		final JPanel shipTab = new JPanel();
		shipTab.setBackground(Color.BLACK);
		mapPane.addTab("Ship", null, shipTab, null);
		shipTab.setLayout(new GridLayout(1, 0, 0, 0));
		
		scrollPane = new JScrollPane();
		shipTab.add(scrollPane);
		
		cargoModel = new DefaultListModel();
		cargoList = new JList(cargoModel);
		cargoList.setBackground(Color.BLACK);
		cargoList.setForeground(Color.WHITE);
		scrollPane.setViewportView(cargoList);
		
		cargoTitleLabel = new JLabel("Cargo Contents");
		cargoTitleLabel.setHorizontalAlignment(SwingConstants.CENTER);
		cargoTitleLabel.setBackground(Color.BLACK);
		cargoTitleLabel.setForeground(Color.BLACK);
		cargoTitleLabel.setFont(listTitleFont);
		scrollPane.setColumnHeaderView(cargoTitleLabel);
		scrollPane.setBackground(Color.BLACK);
	}
	
	/**
	 * Getter for systemLabel instance variable
	 * @return systemLabel instance variable
	 */
	public JLabel getSystemLabel() {
		return systemLabel;
	}
	
	/**
	 * Getter for techLevelLabel instance variable
	 * @return techLevelLabel instance variable
	 */
	public JLabel getTechLevelLabel() {
		return techLevelLabel;
	}
	
	/**
	 * Getter for currentFuelLabel instance variable
	 * @return currentFuelLabel instance variable
	 */
	public JLabel getCurrentFuelLabel() {
		return currentFuelLabel;
	}
	
	/**
	 * Getter for fuelCostLabel instance variable
	 * @return fuelCostLabel instance variable
	 */
	public JLabel getFuelCostLabel() {
		return fuelCostLabel;
	}
	
	/**
	 * Getter for travelButton instance variable
	 * @return travelButton instance variable
	 */
	public JButton getTravelButton() {
		return travelButton;
	}
	
	/**
	 * Getter for saveButton instance variable
	 * @return saveButton instance variable
	 */
	public JButton getSaveButton() {
		return saveButton;
	}
	
	/**
	 * Getter for currSystem instance variable
	 * @return currSystem instance variable
	 */
	public SolarSystem getCurrSystem() {
		return currSystem;
	}
	
	/**
	 * Setter for currSystem instance variable
	 * @param currSystem new instance variable
	 */
	public void setCurrSystem(SolarSystem currSystem) {
		this.currSystem = currSystem;
	}
	
	/**
	 * Setter for cargoModel instance variable
	 * @param cargoModel new instance variable
	 */
	public void setCargoModel(DefaultListModel cargoModel) {
		this.cargoModel = cargoModel;
	}

	/**
	 * Getter for cargoList instance variable
	 * @return cargoList instance variable
	 */
	public JList getCargoList() {
		return cargoList;
	}
	
	/**
	 * Getter for cargoModel instance variable
	 * @return cargoModel instance variable
	 */
	public DefaultListModel getCargoModel() {
		return cargoModel;
	}
	
	/**
	 * Getter for attributeLabel instance variable
	 * @return attributeLabel instance variable
	 */
	public JLabel getAttributeLabel() {
		return attributeLabel;
	}
	
	//TODO: Do this the right way instead of this horribly hacked-together kludge BS
	/**
	 * populates cargo list
	 */
	public void populateCargoList() {
		//sets cargo list in side panel to be the cargo list in marketplace panel
		final Marketplace market = spaceTradersParent.getMarketplace();
		final DefaultListModel model = new DefaultListModel();
		final Map<TradeGood, Integer> cargoMap = 
		      new HashMap<TradeGood, Integer>();
		for(Map.Entry<TradeGood, InventoryItem> entry : 
			market.getSellMap().entrySet()) {
			cargoMap.put(entry.getKey(), (Integer) (
					entry.getValue()).getQuantity());
		}
		for(Map.Entry<TradeGood, Integer> entry : cargoMap.entrySet()) {
			model.addElement(entry);
		}
		final JList list = spaceTradersParent.getUniverseController()
				.getSideView().getCargoList();

		spaceTradersParent.getUniverseController().getSideView().setCargoModel(model);
		list.setModel(model);
	}

	/**
	 * method for saving
	 * @param filename the filename
	 * @throws IOException throws an exception for IO
	 */
	public void writeObjectWithFilename(String filename) {
		try {
			final ObjectOutputStream out = new ObjectOutputStream(
					new FileOutputStream(filename + ".dat"));     
			
			try {
				out.writeObject(this);
			} finally {
				out.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
	
}
